package com.xtravel.tweet.adapter;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.text.Html;
import android.text.SpannableStringBuilder;
import android.text.method.LinkMovementMethod;
import android.text.style.ClickableSpan;
import android.text.style.URLSpan;
import android.util.DisplayMetrics;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.*;
import com.google.gson.reflect.TypeToken;
import com.handmark.pulltorefresh.library.PullToRefreshListView;
import com.lidroid.xutils.BitmapUtils;
import com.xtravel.R;
import com.xtravel.common.activity.BrowserActivity;
import com.xtravel.common.adapter.BaseDataAdapter;
import com.xtravel.common.api.BaseRequest;
import com.xtravel.common.api.domain.BaseJson;
import com.xtravel.common.constant.BrowserOpenType;
import com.xtravel.common.helper.JsonHelper;
import com.xtravel.common.helper.ShareSdkHelper;
import com.xtravel.common.widget.TweetImageView;
import com.xtravel.tweet.activity.ImageDetailActivity;
import com.xtravel.tweet.activity.TweetActivity;
import com.xtravel.tweet.api.TweetJson;
import com.xtravel.tweet.api.TweetRequest;
import com.xtravel.tweet.database.dao.TweetDao;
import com.xtravel.tweet.database.dto.Tweet;
import com.xtravel.tweet.database.dto.TweetSource;


import java.sql.SQLException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

@SuppressLint("SimpleDateFormat")
public class TweetListAdapter extends BaseDataAdapter<Tweet> {
    private ListView lvTweet;
    private PullToRefreshListView prlvTweet;
    private View footerView;
    private TextView tvFooterText;
    private BitmapUtils bitmapUtils;
    private Context context;
    private  android.support.v4.app.Fragment fragment;
    private LayoutInflater mInflater;
    private boolean isLatest;
    private boolean noData = false;

    /**
     * 是否已经加载数据。有可能仅仅是加载的本地缓存
     */
    private Boolean isInited = false;

    /**
     * 是否正在加载数据，如果正在加载，则不进行加载，如果没有，则加载，
     * 用于用户数滑动列表
     */
    private Boolean isRefreshing = false;

    final Html.ImageGetter linkImageGetter = new Html.ImageGetter() {
        private HashMap<String, Drawable> cache = new HashMap<String, Drawable>();

        @Override
        public Drawable getDrawable(String source) {
            if (cache.containsKey(source))
                return cache.get(source);

            BitmapDrawable drawable = null;
            int rId = Integer.parseInt(source);
            drawable = (BitmapDrawable) context.getResources().getDrawable(rId);

            DisplayMetrics dm = new DisplayMetrics();
            ((Activity) context).getWindowManager().getDefaultDisplay().getMetrics(dm);

            drawable.setBounds(0, (int) (-5 * dm.density), drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());
            drawable.setGravity(Gravity.TOP);
            return drawable;
        }
    };

    public TweetListAdapter(android.support.v4.app.Fragment fragment, Context context, PullToRefreshListView prlvTweet, View footerView, List<Tweet> data, BitmapUtils bitmapUtils, Handler dataCallbackHandler) {
        super(data, dataCallbackHandler);
        this.context = context;
        this.fragment = fragment;
        this.mInflater = LayoutInflater.from(context);
        this.bitmapUtils = bitmapUtils;

        this.lvTweet = prlvTweet.getRefreshableView();
        this.prlvTweet = prlvTweet;
        this.footerView = footerView;
        this.footerView.setVisibility(View.GONE);
        this.tvFooterText = (TextView) footerView.findViewById(R.id.tvFooterText);
    }

    @SuppressLint("NewApi")
    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        final ViewHolder holder;
        if (convertView == null) {
            holder = new ViewHolder();
            convertView = mInflater.inflate(R.layout.tweet_main_list_item, null);
            holder.txtTitle = (TextView) convertView.findViewById(R.id.txtTitle);
            holder.publishTime = (TextView) convertView.findViewById(R.id.publishTime);
            holder.txtMessage = (TextView) convertView.findViewById(R.id.txtMessage);
            holder.imgGrid = (GridView) convertView.findViewById(R.id.imageGrid);
            holder.lyImagePannel = (LinearLayout) convertView.findViewById(R.id.lyImagePannel);
            holder.imgSingle = (TweetImageView) convertView.findViewById(R.id.imageSignle);
            holder.isHot = (ImageView) convertView.findViewById(R.id.isHot);
            holder.tellFriend = (LinearLayout) convertView.findViewById(R.id.btn_tell_friend);
            holder.tagsListView = (LinearLayout) convertView.findViewById(R.id.tag_container);
            holder.retweetCountView = (TextView)convertView.findViewById(R.id.retweetCount);
            holder.likeCountView = (TextView)convertView.findViewById(R.id.likeCount);
            holder.likeCountImg = (ImageView)convertView.findViewById(R.id.like_count_img);
            holder.likeCountLayout = (LinearLayout)convertView.findViewById(R.id.like_count_lauout);
            convertView.setTag(holder);
        } else {
            holder = (ViewHolder) convertView.getTag();
        }

        final Tweet tweet = (Tweet) getItem(position);
        if (!tweet.equals(holder.tweet)) {
            holder.tweet = tweet;
            holder.txtTitle.setText(tweet.title);
            holder.publishTime.setText(getDisplayTime(tweet.getOnlineTime(), position));
            setTextViewHTML(holder.txtMessage, tweet);
            int hotVisible = (tweet.isPerfect ? View.VISIBLE : View.GONE);
            holder.isHot.setVisibility(hotVisible);
            int imageVisible = (tweet.getImageSources().size() <= 1 ? View.GONE : View.VISIBLE);
            holder.imgGrid.setVisibility(imageVisible);
            holder.imgGrid.setAdapter(new ImageListAdapter(context, this.bitmapUtils, tweet.getImageSources()));
            //set tag
            if(tweet.tags != null && tweet.tags.length() > 0) {
                holder.tagsListView.removeAllViews();
                Drawable bg = context.getResources().getDrawable(R.drawable.ic_tweet_tag);
                int cl = context.getResources().getColor(R.color.cl_tweet_tag);
                String[] tagList = tweet.tags.split(" ");
                for (String tag : tagList) {
                    TextView tagView = new TextView(context);
                    tagView.setText(tag);
                    tagView.setBackground(bg);
                    tagView.setTextSize(12);
                    tagView.setTextColor(cl);
                    tagView.setGravity(Gravity.CENTER);
                    LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT);
                    lp.setMargins(0, 0, 10, 0);
                    tagView.setLayoutParams(lp);
                    holder.tagsListView.addView(tagView);
                }
                holder.tagsListView.setVisibility(View.VISIBLE);
            } else{
                holder.tagsListView.setVisibility(View.GONE);
            }
            //设置点赞数
            if(tweet.isWish){
                holder.likeCountImg.setSelected(true);
            }
           holder.retweetCountView.setText(String.valueOf(tweet.viewCount));
           holder.likeCountView.setText(String.valueOf(tweet.wishCount));
           holder.likeCountLayout.setOnClickListener(new OnClickListener() {
               @Override
               public void onClick(View view) {
                   new AsyncTask<Void, Void, BaseJson>() {
                       @Override
                       protected BaseJson doInBackground(Void... params) {
                           String jsonString = new BaseRequest().api("/tweet/wish/?", tweet.id);
                           BaseJson json = JsonHelper.fromJson(jsonString, new TypeToken<BaseJson>() {
                           });
                           return json;
                       }
                       @Override
                       protected void onPostExecute(BaseJson json) {
                           if (json != null && json.getCode() == 200) {
                               if(tweet.isWish){
                                   holder.likeCountImg.setSelected(false);
                                   tweet.isWish = false;
                                   tweet.wishCount --;
                                   holder.likeCountView.setText(String.valueOf(tweet.wishCount));
                               }else {
                                   holder.likeCountImg.setSelected(true);
                                   tweet.isWish = true;
                                   tweet.wishCount ++;
                                   holder.likeCountView.setText(String.valueOf(tweet.wishCount));
                               }
                           }
                       }
                   }.execute();
               }
           });


            //share
            holder.tellFriend.setTag(tweet);
            holder.tellFriend.setOnClickListener(new OnClickListener() {
                @Override
                public void onClick(View arg0) {
                    Tweet tweet = (Tweet) arg0.getTag();
                    ArrayList<String> imgUrls = new ArrayList<>();
                    if (tweet.getImageSources().size() > 0) {
                        for (TweetSource t : tweet.getImageSources()) {
                            imgUrls.add(t.largeUrl);
                        }
                    }

                    //内容url
                    String url = String.format(context.getString(R.string.tweet_detail_url), tweet.id);
                    ShareSdkHelper.share(context, context.getResources().getString(R.string.share_tweet_title), tweet.content, url, imgUrls);
                }
            });

            if (tweet.getImageSources().size() == 1) {
                holder.lyImagePannel.setVisibility(View.VISIBLE);
                holder.imgSingle.setImageUrl(bitmapUtils, tweet.getImageSources().get(0).largeUrl, 240, 240);

                holder.imgSingle.setTag(tweet.getImageSources().get(0).largeUrl);
                holder.imgSingle.setOnClickListener(new OnClickListener() {
                    @Override
                    public void onClick(View imageView) {
                        String imageUrl = (String) imageView.getTag();
                        Intent intent = new Intent(context, ImageDetailActivity.class);
                        Bundle bundle = new Bundle();
                        bundle.putStringArray("url", new String[]{imageUrl});
                        bundle.putInt("start", 0);
                        intent.putExtras(bundle);
                        context.startActivity(intent);
                    }
                });
            } else {
                holder.lyImagePannel.setVisibility(View.GONE);
            }
        }

/*        convertView.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(final View v) {
                new AsyncTask<Void, Void, BaseJson>() {
                    @Override
                    protected BaseJson doInBackground(Void... params) {
                        String jsonString = new BaseRequest().api("tweet/view/?", tweet.id);
                        BaseJson json = JsonHelper.fromJson(jsonString, new TypeToken<BaseJson>() {
                        });
                        return json;
                    }
                    @Override
                    protected void onPostExecute(BaseJson json) {
                        if (json != null && json.getCode() == 200) {
                            if(!tweet.isView){
                                holder.tweet.viewCount ++ ;
                                tweet.isView = true;
                            }
                            holder.retweetCountView.setText(String.valueOf(holder.tweet.viewCount));
                            Tweet tw = ((ViewHolder) v.getTag()).tweet;
                            Intent intent = new Intent(context, TweetActivity.class);
                            intent.putExtra("tweetId", tw.id);
                            fragment.startActivityForResult(intent, 1);
                            //context.startActivity(intent);
                        }
                    }
                }.execute();

            }
        });*/

        return convertView;
    }

    private String getDisplayTime(Long lCreatedTime, int p) {
        lCreatedTime = lCreatedTime == null ? 0L : lCreatedTime;
        Date createdTime = new Date(lCreatedTime);
        Date nowTime = new Date();

        Long now = nowTime.getTime();
        Long diff = now - lCreatedTime;

        Calendar oldCal = Calendar.getInstance();
        Calendar newCal = Calendar.getInstance();

        oldCal.setTime(createdTime);
        newCal.setTime(nowTime);

        if (diff < 60 * 1000) {
            return "刚刚";
        }
        if (diff < 60 * 60 * 1000) {
            return (diff / (60 * 1000)) + "分钟前";
        }
        if (newCal.get(Calendar.DAY_OF_YEAR) == oldCal.get(Calendar.DAY_OF_YEAR)) {
            return new SimpleDateFormat("HH:mm").format(createdTime);
        }
        if (Math.abs(newCal.get(Calendar.DAY_OF_YEAR) - oldCal.get(Calendar.DAY_OF_YEAR)) == 1) {
            return "昨天 " + new SimpleDateFormat("HH:mm").format(createdTime);
        }
        if (newCal.get(Calendar.YEAR) == oldCal.get(Calendar.YEAR)) {
            return new SimpleDateFormat("MM月dd日").format(createdTime);
        }

        return new SimpleDateFormat("yyyy年").format(createdTime);
    }

    private String parseContent(String source) {
        String destString = source;
        Pattern pattern = Pattern.compile("[a-zA-z]+://[^\\s]*?\\.(com|net|info|cn|me|tw|fr)[^\u4e00-\u9fa5\\s]*");// .compile("(http://|ftp://|https://|www){0,1}[^\u4e00-\u9fa5\\s]*?\\.(com|net|info|cn|me|tw|fr)[^\u4e00-\u9fa5\\s]*");//[a-zA-z]+://[^\\s]*");
        Matcher matcher = pattern.matcher(source);
        while (matcher.find()) {
            String r = matcher.group();
            destString = destString.replace(r, String.format("<a href='%s'><img src='%s' /></a>", r, R.drawable.img_tweet_link));
        }

        return destString;
    }

    protected void makeLinkClickable(SpannableStringBuilder strBuilder, final URLSpan span, final Tweet tweet) {
        int start = strBuilder.getSpanStart(span);
        int end = strBuilder.getSpanEnd(span);
        int flags = strBuilder.getSpanFlags(span);

        ClickableSpan clickable = new ClickableSpan() {
            @Override
            public void onClick(View view) {
                Intent intent = new Intent(context, BrowserActivity.class);
                Bundle bundle = new Bundle();
                bundle.putString("title", "资讯详情");
                bundle.putString("url", span.getURL());
                bundle.putString("content", tweet.content);
                bundle.putString("opentype", BrowserOpenType.Link_Share);
                //分享查看内容的链接地址
                bundle.putString("shareurl", String.format(context.getString(R.string.tweet_detail_url), tweet.id));
                bundle.putString("sharetitle", context.getResources().getString(R.string.share_tweet_title));
                ArrayList<String> imgUrls = new ArrayList<>();
                for (TweetSource t : tweet.getImageSources()) {
                    imgUrls.add(t.largeUrl);
                }

                bundle.putStringArrayList("imgurl", imgUrls);
                intent.putExtras(bundle);
                context.startActivity(intent);
            }
        };

        strBuilder.setSpan(clickable, start, end, flags);
        strBuilder.removeSpan(span);
    }

    protected void setTextViewHTML(TextView txtMessage, Tweet tweet) {
        String htmText = parseContent(tweet.content);
        CharSequence sequence = Html.fromHtml(htmText, linkImageGetter, null);
        SpannableStringBuilder strBuilder = new SpannableStringBuilder(sequence);
        URLSpan[] urls = strBuilder.getSpans(0, sequence.length(), URLSpan.class);
        for (URLSpan span : urls) {
            makeLinkClickable(strBuilder, span, tweet);
        }

        txtMessage.setMovementMethod(LinkMovementMethod.getInstance());
        txtMessage.setText(strBuilder);
    }

    @Override
    public void getData(Object args) {
        this.isLatest = Boolean.parseBoolean(args.toString());
        if (!this.isLatest) {
            if (isRefreshing) {
                return;
            }
            isRefreshing = true;
        }

        if (this.isLatest && !this.isInited) {
            try {
                this.dataList = new TweetDao(context).getAll();
                if (this.dataList.size() > 0) {
                    lvTweet.setBackgroundColor(context.getResources().getColor(R.color.transparant));
                }
                notifyDataSetChanged();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }

        Long sinceId = 0L, maxId = 0L;
        if (isLatest) {
            sinceId = getMaxId();
        } else {
            maxId = getMinId();
        }

        new AsyncTask<Long, Void, TweetJson>() {

            @Override
            protected TweetJson doInBackground(Long... params) {
                TweetRequest request = new TweetRequest();
                return request.weiboList(params[0], params[1], 20);
            }

            @Override
            protected void onPostExecute(TweetJson tweetJson) {
                prlvTweet.onRefreshComplete();

                if (tweetJson == null) {
                    if (dataList.size() == 0) {
                        lvTweet.setBackgroundResource(R.drawable.no_data);
                    }
                    return;
                }
                int color = context.getResources().getColor(R.color.transparant);
                lvTweet.setBackgroundColor(color);

                List<Tweet> data = tweetJson.getResult();
                updateData(data);

                if (!isLatest) {
                    isRefreshing = false;
                }

                footerView.setVisibility(View.VISIBLE);
                if (data != null && data.size() == 0 && !isLatest) {
                    tvFooterText.setText(R.string.str_no_data);
                    noData = true;
                }
            }
        }.execute(sinceId, maxId);
    }

    @Override
    public void updateData(List<Tweet> data) {
        updateDataSource(data, this.isLatest);
    }

    public void updateDataSource(List<Tweet> items, boolean isBegin) {
        if (items == null || items.size() == 0) {
            return;
        }

        if (!isInited && isBegin && items.size() > 0) {
            dataList = new ArrayList<Tweet>();
            isInited = true;
            try {
                new TweetDao(context).saveAll(items);
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }

        List<Tweet> newItems = new ArrayList<Tweet>();
        for (Tweet tweet : items) {
            boolean exist = isExist(tweet);
            if (!exist)
                newItems.add(tweet);
        }

        if (isBegin)
            addRangeAtBegin(newItems);
        else
            addRangeAtEnd(newItems);
        notifyDataSetChanged();
    }

    public static int getCurrentTimezoneOffset() {
        TimeZone tz = TimeZone.getDefault();
        Calendar cal = Calendar.getInstance(tz);
        int offsetInMillis = tz.getOffset(cal.getTimeInMillis());
        return offsetInMillis;
    }

    public final class ViewHolder {
        public Tweet tweet;
        public TextView txtTitle;
        public ImageView isHot;
        public TextView publishTime;
        public TextView addFavorite;
        public TextView txtMessage;
        public GridView imgGrid;
        public LinearLayout tagsListView;
        public LinearLayout lyImagePannel;
        public TweetImageView imgSingle;
        public LinearLayout tellFriend;
        public TextView retweetCountView;
        public TextView likeCountView;
        public ImageView likeCountImg;
        public LinearLayout likeCountLayout;
    }

}
